# Copyright (c) 2025 Li Auto Inc. and its affiliates
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

#
# base_rules.mk
#

LOCAL_MODULE := $(strip $(firstword $(LOCAL_MODULE)))
ifeq ($(LOCAL_MODULE),)
    $(error $(LOCAL_PATH): LOCAL_MODULE is not defined)
endif

ifneq ($(filter $(LOCAL_MODULE),$(ALL_MODULES)),)
$(error "'$(LOCAL_MODULE)' has been already introduced in.")
endif

LOCAL_SRCS += $(LOCAL_SRCS_$(TARGET_PRODUCT_UPPER))
LOCAL_INC_DIR += $(LOCAL_INC_DIR_$(TARGET_PRODUCT_UPPER))
LOCAL_CFLAGS += $(LOCAL_CFLAGS_$(TARGET_PRODUCT_UPPER))
LOCAL_LFLAGS += $(LOCAL_LFLAGS_$(TARGET_PRODUCT_UPPER))
LOCAL_TEST_CFGS += $(LOCAL_TEST_CFGS_$(TARGET_PRODUCT_UPPER))
LOCAL_IDL_FILES += $(LOCAL_IDL_FILES_$(TARGET_PRODUCT_UPPER))
LOCAL_RPC_FILES += $(LOCAL_RPC_FILES_$(TARGET_PRODUCT_UPPER))
LOCAL_TEST_ROBOT_CFGS += $(LOCAL_TEST_ROBOT_CFGS_$(TARGET_PRODUCT_UPPER))
LOCAL_STATIC_LIBRARIES += $(LOCAL_STATIC_LIBRARIES_$(TARGET_PRODUCT_UPPER))
LOCAL_SHARED_LIBRARIES += $(LOCAL_SHARED_LIBRARIES_$(TARGET_PRODUCT_UPPER))
LOCAL_TEST_PROFILES += $(LOCAL_TEST_PROFILES_$(TARGET_PRODUCT_UPPER))
LOCAL_EXPORT_INC_DIR += $(LOCAL_EXPORT_INC_DIR_$(TARGET_PRODUCT_UPPER))
LOCAL_EXPORT_CFLAGS += $(LOCAL_EXPORT_CFLAGS_$(TARGET_PRODUCT_UPPER))
LOCAL_EXPORT_LFLAGS += $(LOCAL_EXPORT_LFLAGS_$(TARGET_PRODUCT_UPPER))

LOCAL_CFG_FILES ?= $(LOCAL_CFG_FILES_$(TARGET_PRODUCT_UPPER))

LOCAL_LINK_SCRIPT := $(LOCAL_LINK_SCRIPT_$(TARGET_PRODUCT_UPPER))
LOCAL_CFG_OPTIONS+=$(LOCAL_CFG_OPTIONS_$(TARGET_PRODUCT_UPPER))
LOCAL_IDL_OPTIONS+=$(LOCAL_IDL_OPTIONS_$(TARGET_PRODUCT_UPPER))
LOCAL_RPC_OPTIONS+=$(LOCAL_RPC_OPTIONS_$(TARGET_PRODUCT_UPPER))

LOCAL_OUT:=$(call get_module_outdir,$(LOCAL_MODULE))
LOCAL_TARGET:=$(call get_module_target,$(LOCAL_MODULE))

LOCAL_C_SRCS:=$(filter %.c,$(LOCAL_SRCS))
LOCAL_CPP_SRCS:=$(filter %.cpp,$(LOCAL_SRCS))

LOCAL_C_OBJS:=$(LOCAL_C_SRCS:%.c=$(LOCAL_OUT)/%.o)
LOCAL_C_DEPS:=$(LOCAL_C_SRCS:%.c=$(LOCAL_OUT)/%.d)

LOCAL_CPP_OBJS:=$(LOCAL_CPP_SRCS:%.cpp=$(LOCAL_OUT)/%.o)
LOCAL_CPP_DEPS:=$(LOCAL_CPP_SRCS:%.cpp=$(LOCAL_OUT)/%.d)

LOCAL_TEST_PROFILES:= $(wildcard $(patsubst %,$(LOCAL_PATH)/%,$(LOCAL_TEST_PROFILES)))

################################################################################
# The following is for these source files and headers generated by IDL Tool.
ifneq ($(strip $(LOCAL_IDL_FILES)),)
    LOCAL_GEN_IDL_SRCS:=$(foreach idl, $(LOCAL_IDL_FILES),                                   \
                                  $(call mvbs_idl_setup, $(addprefix $(LOCAL_PATH)/,$(idl)), \
                                                         $(LOCAL_OUT)/gen/$(dir $(idl)),     \
                                                         $(LOCAL_IDL_OPTIONS)))
endif

################################################################################
# The following is for these source files and headers generated by RPC Tool.
ifneq ($(strip $(LOCAL_RPC_FILES)),)
    LOCAL_GEN_RPC_SRCS:=$(foreach rpc, $(LOCAL_RPC_FILES),                                   \
                                  $(call mvbs_rpc_setup, $(addprefix $(LOCAL_PATH)/,$(rpc)), \
                                                         $(LOCAL_OUT)/gen/$(dir $(rpc)),     \
                                                         $(LOCAL_RPC_OPTIONS)))
endif

################################################################################
# This part is for test robot
ifneq ($(strip $(LOCAL_TEST_ROBOT_CFGS)),)
    LOCAL_GEN_ROBOT_FILES:=$(foreach case, $(LOCAL_TEST_ROBOT_CFGS),                                    \
                                     $(call mvbs_test_robot_setup, $(addprefix $(LOCAL_PATH)/,$(case)), \
                                                                   $(LOCAL_OUT)/gen/$(basename $(notdir $(case)))))
    LOCAL_GEN_TEST_MVBS_CFGS+=$(foreach cfg, $(filter %.xml, $(LOCAL_GEN_ROBOT_FILES)),         \
                                        $(call mvbs_cfg_test_setup, $(cfg),                     \
                                                                    $(cfg:%.xml=%.c),           \
                                                                    $(LOCAL_CFG_OPTIONS)))
    LOCAL_GEN_ROBOT_SRCS:= $(filter %.c, $(LOCAL_GEN_ROBOT_FILES))
    $(LOCAL_GEN_ROBOT_SRCS): | $(filter %.h, $(LOCAL_GEN_IDL_SRCS))
    LOCAL_TEST_PROFILES+=$(filter %TestProfile, $(LOCAL_GEN_ROBOT_FILES))
    LOCAL_GEN_ROBOT_OBJS:=$(patsubst %.c,%.o,$(LOCAL_GEN_ROBOT_SRCS))
    $(LOCAL_GEN_ROBOT_OBJS): | $(filter %.h, $(LOCAL_GEN_ROBOT_SRCS)) $(LOCAL_GEN_TEST_MVBS_CFGS)
endif

################################################################################
# The following is for these source files and headers generated by CFG Tool.
ifneq ($(strip $(LOCAL_TEST_CFGS)),)
    LOCAL_TEST_CFGS_EXT:= $(foreach item, $(LOCAL_TEST_CFGS),$(if $(findstring %, $(item)), $(item),))
    LOCAL_TEST_CFGS_LST:= $(foreach item, $(LOCAL_TEST_CFGS),$(if $(findstring %, $(item)), ,$(item)))

    LOCAL_GEN_TEST_MVBS_CFGS+=$(foreach cfg, $(LOCAL_TEST_CFGS_LST),                                     \
                                        $(call mvbs_cfg_test_setup, $(addprefix $(LOCAL_PATH)/,$(cfg)),  \
                                                                    $(LOCAL_OUT)/gen/$(cfg:%.xml=%.c),	 \
                                                                    $(LOCAL_CFG_OPTIONS)))

    LOCAL_GEN_TEST_MVBS_CFGS+=$(foreach cfg, $(LOCAL_TEST_CFGS_EXT),                                         \
                                        $(eval _cfg_tuple := $(subst %, ,$(cfg)))                            \
                                        $(eval _cfg_xml   := $(strip $(word 1,$(_cfg_tuple))))               \
                                        $(eval _cfg_opt   := $(strip $(word 2,$(_cfg_tuple))))               \
                                        $(call mvbs_cfg_test_setup, $(addprefix $(LOCAL_PATH)/,$(_cfg_xml)), \
                                                                    $(LOCAL_OUT)/gen/$(_cfg_xml:%.xml=%.c),  \
                                                                    $(LOCAL_CFG_OPTIONS) $(_cfg_opt)))
endif

ifneq ($(strip $(LOCAL_CFG_FILES)),)
    LOCAL_CFG_FILES_EXT:= $(foreach item, $(LOCAL_CFG_FILES),$(if $(findstring %, $(item)), $(item),))
    LOCAL_CFG_FILES_LST:= $(foreach item, $(LOCAL_CFG_FILES),$(if $(findstring %, $(item)), ,$(item)))

    LOCAL_GEN_MVBS_CFGS+=$(foreach cfg, $(LOCAL_CFG_FILES_LST),                                               \
                                         $(call mvbs_cfg_setup, $(addprefix $(LOCAL_PATH)/,$(cfg)),      \
                                                                $(LOCAL_OUT)/gen/$(cfg:%.xml=%.c),	 \
                                                                $(LOCAL_CFG_OPTIONS)))

    LOCAL_GEN_MVBS_CFGS+=$(foreach cfg, $(LOCAL_CFG_FILES_EXT),                                                    \
                                         $(eval _cfg_tuple := $(subst %, ,$(cfg)))                            \
                                         $(eval _cfg_xml   := $(strip $(word 1,$(_cfg_tuple))))               \
                                         $(eval _cfg_opt   := $(strip $(word 2,$(_cfg_tuple))))               \
                                         $(call mvbs_cfg_setup, $(addprefix $(LOCAL_PATH)/,$(_cfg_xml)),      \
                                                                     $(LOCAL_OUT)/gen/$(_cfg_xml:%.xml=%.c),  \
                                                                     $(LOCAL_CFG_OPTIONS) $(_cfg_opt)))
endif

LOCAL_GEN_SRCS:= $(LOCAL_GEN_IDL_SRCS) $(LOCAL_GEN_RPC_SRCS) $(LOCAL_GEN_ROBOT_SRCS) $(LOCAL_GEN_MVBS_CFGS)

ifneq ($(strip $(LOCAL_GEN_SRCS) $(LOCAL_GEN_TEST_MVBS_CFGS)),)
LOCAL_EXTRA_SRCS:= $(filter %.c, $(LOCAL_GEN_SRCS))
LOCAL_EXTRA_OBJS:=$(LOCAL_EXTRA_SRCS:%.c=%.o)
LOCAL_EXTRA_DEPS:=$(LOCAL_EXTRA_OBJS:%.o=%.d)

LOCAL_EXTRA_INCS:= $(sort $(dir $(filter %.h, $(LOCAL_GEN_SRCS)) $(LOCAL_GEN_TEST_MVBS_CFGS) $(LOCAL_OUT)/gen/))

$(LOCAL_C_OBJS) $(LOCAL_CPP_OBJS): | $(filter %.h, $(LOCAL_GEN_SRCS)) $(LOCAL_GEN_TEST_MVBS_CFGS)

endif

ifneq ($(strip $(LOCAL_GEN_MVBS_CFGS)),)
$(LOCAL_GEN_MVBS_CFGS): | $(filter %.h, $(LOCAL_GEN_SRCS))
endif

ifneq ($(filter %.d, $(LOCAL_C)DEPS) $(LOCAL_CPP_DEPS) $(LOCAL_EXTRA_DEPS)),)
-include $(LOCAL_C_DEPS) $(LOCAL_CPP_DEPS) $(LOCAL_EXTRA_DEPS)
endif

################################################################################
# Introduce export_includes target
import_includes := $(LOCAL_OUT)/import_includes

import_includes_deps := $(strip \
                        $(foreach l,$(LOCAL_STATIC_LIBRARIES), $(call get_module_outdir,$l)/export_includes))

$(import_includes): PRIVATE_IMPORT_EXPORT_INCLUDES := $(import_includes_deps)
$(import_includes): $(import_includes_deps)
	@echo Import includes file: $@
	$(hide) mkdir -p $(dir $@) && rm -f $@
ifneq ($(import_includes_deps),)
	$(hide) for f in $(PRIVATE_IMPORT_EXPORT_INCLUDES); do	\
		cat $$f >> $@;					\
	done
else
	$(hide) touch $@
endif

$(LOCAL_C_OBJS) $(LOCAL_CPP_OBJS)  $(LOCAL_EXTRA_OBJS): $(import_includes)


################################################################################
# Introduce export_includes target
ifneq ($(filter SHARED_LIBRARIES STATIC_LIBRARIES HEADER_LIBRARIES,$(LOCAL_MODULE_CLASS)),)
export_includes := $(LOCAL_OUT)/export_includes
export_cflags := $(foreach d, $(addprefix $(LOCAL_PATH)/,$(LOCAL_EXPORT_INC_DIR)),-I $(d)) $(LOCAL_EXPORT_CFLAGS)

$(export_includes): PRIVATE_EXPORT_CFLAGS := $(export_cflags)

export_include_deps := $(strip \
                       $(foreach l,$(LOCAL_STATIC_LIBRARIES), $(call get_module_outdir,$l)/export_includes))

$(export_includes): PRIVATE_REEXPORTED_INCLUDES := $(export_include_deps)
$(export_includes): $(export_include_deps)
	@echo Export includes file: $< -- $@
	$(hide) mkdir -p $(dir $@) && rm -f $@.tmp && touch $@.tmp
ifneq ($(export_cflags),)
	$(hide) echo "$(PRIVATE_EXPORT_CFLAGS)" >>$@.tmp
endif
ifneq ($(export_include_deps),)
	$(hide) for f in $(PRIVATE_REEXPORTED_INCLUDES); do	\
		cat $$f >> $@.tmp;				\
		done
endif
	$(hide) if cmp -s $@.tmp $@ ; then			\
		rm $@.tmp ;					\
	else							\
		mv $@.tmp $@ ;					\
	fi
endif
################################################################################
ifneq ($(filter $(LOCAL_MODULE),$(ALL_MODULES)),)
    $(warning ALL_MODULES = $(ALL_MODULES))
    $(error $(LOCAL_MODULE): has already defined in $(ALL_MODULES.$(LOCAL_MODULE).PATH))
endif

ALL_MODULES := $(ALL_MODULES) $(LOCAL_MODULE)

ALL_MODULES.$(LOCAL_MODULE).PATH          :=$(LOCAL_PATH)
ALL_MODULES.$(LOCAL_MODULE).CLASS         :=$(LOCAL_MODULE_CLASS)
ALL_MODULES.$(LOCAL_MODULE).BUILT         :=$(ALL_MODULES.$(LOCAL_MODULE).BUILT) $(LOCAL_TARGET)

ALL_MODULES.$(LOCAL_MODULE).TEST_PROFILES :=$(LOCAL_TEST_PROFILES)

ALL_MODULES.$(LOCAL_MODULE).REQUIRED      := $(LOCAL_SHARED_LIBRARIES) \
                                             $(LOCAL_REQUIRED_MODULES)

ALL_MODULES.$(LOCAL_MODULE).STATIC_LIB    :=$(LOCAL_STATIC_LIBRARIES) \
                                            $(call module-dependent-static-libraries, $(LOCAL_STATIC_LIBRARIES))

ALL_MODULES.$(LOCAL_MODULE).SHARED_LIB    :=$(LOCAL_SHARED_LIBRARIES)

info-%: FORCE
	@echo "----------- Module Name: $* -----------"
	@echo "ALL_MODULES.$*.PATH          =  $(ALL_MODULES.$*.PATH)"
	@echo "ALL_MODULES.$*.CLASS         =  $(ALL_MODULES.$*.CLASS)"
	@echo "ALL_MODULES.$*.BUILT         =  $(ALL_MODULES.$*.BUILT)"
	@echo "ALL_MODULES.$*.TEST_PROFILES =  $(ALL_MODULES.$*.TEST_PROFILES)"
	@echo "ALL_MODULES.$*.STATIC_LIB    =  $(ALL_MODULES.$*.STATIC_LIB)"
# 	@echo "ALL_MODULES.$*.REQUIRED      =  $(ALL_MODULES.$*.REQUIRED)"
# 	@echo "ALL_MODULES.$*.SHARED_LIB    =  $(ALL_MODULES.$*.SHARED_LIB)"
# 	@echo "ALL_MODULES.$*.HEADER_LIB    =  $(ALL_MODULES.$*.HEADER_LIB)"

# vim:ft=make
#
